# -*- coding: utf-8 -*-
from twisted.python.util import sibpath
from nevow.loaders import xmlfile
from nevow.athena import LiveElement, expose
# DB stuff
from axiom.item import Item
from axiom.attributes import text, timestamp, reference, AND, OR
from axiom.store import Store
#date related
from epsilon import extime
import datetime
import time
import operator

class JST(datetime.tzinfo):
    def tzname(self, dt):
        return 'JST'
    def utcoffset(self, dt):
        return datetime.timedelta(hours = +9)
    def dst(self, dt):
        return datetime.timedelta(0)

class ChatWords(Item):
    typeName = 'archive'
    schemaVersion = 1
    who = text()
    says = text()
    date = timestamp()
    library = text()

class ChatLibrary(Item):
    typeName = 'Library'
    schemaVersion = 1
    name = text()

    def getAllArchive(self, room=u'test'):
        for cw in self.store.query(ChatWords):
            break
        else:
            cw = ChatWords(who= u'かず', says = u'こんにちは', 
                           date = extime.Time(), library = u'test',
                           store = self.store)
        return self.store.query(ChatWords, ChatWords.library == u'test')

    def getLogins(self, room=u'test'):
        for u in self.store.query(User):
            print 'no users found'
        return self.store.query(User, User.myroom==room)

class User(Item):
    typeName = 'User'
    schemaVersion = 1
    username = text() # ユーザ識別情報
    nickname = text() # 表示名
    myroom = text() # room は1つしか入れない。
    # あとで複数にはいれるようにしないといけない。
    
class ChatRoom(object):

    def __init__(self):
        self.chatters = []
        self.store = Store('chat.axiom', debug = False)
        self.library = ChatLibrary(name=u'test', store=self.store)

    def wall(self, message):
        for chatter in self.chatters:
            chatter.wall(message)

    def wallLogins(self, message):
        for chatter in self.chatters:
            chatter.wallLogins(message)

    def tellEverybody(self, who, what):
        archive = ChatWords(who=unicode(who.username), 
                            says=unicode(what),
                            date = extime.Time(),
                            library = u'test',
                            store = self.store)
        for chatter in self.chatters:
            chatter.hear(who.username, what)

    def makeChatter(self):
        cb = ChatterBox(self)
        self.chatters.append(cb)
        return cb


# element to be run with twistd
chat = ChatRoom().makeChatter

class ChatterBox(LiveElement):

    docFactory = xmlfile(sibpath(__file__, 'template.xhtml'))
    jsClass = u'ChatThing.ChatterBox'

    def __init__(self, room):
        self.room = room

    def setUsername(self, username):
        self.username = username
        message = ' * user '+username+' has joined the room'
        self.room.wall(message)
        User(nickname = unicode(username),
             myroom = u'test',
            store=self.room.store)
        self.loginUsers()
        self.history()
    setUsername = expose(setUsername)

    def say(self, message):
        self.room.tellEverybody(self, message)
    say = expose(say)

    def wall(self, message):
        self.callRemote('displayMessage', message)

    # wall と wallLogins は描画先が違うだけだから、後で合体させる.
    def wallLogins(self, message):
        self.callRemote('displayLogins', message)


    def update(self, message, div):
        self.callRemote('updateMessage', message, div)

    def hear(self, username, what):
        self.callRemote('displayUserMessage', username, what)

    def history(self):
        archives = self.room.library.getAllArchive()
        msg = ''
        for arc in archives:
             msg = '(' + arc.date.asHumanly(tzinfo=JST()) + ')' \
                   +  arc.who + ' says: ' + arc.says 
             self.update(msg, u'scrollArea')
    history = expose(history)

    def loginUsers(self, room=u'test'):
        logins = self.room.library.getLogins()
        self.update(u'ログインしているメンバは', u'loginsArea')
        for login in logins:
            self.update(login.nickname, u'loginsArea')
        self.update(u'以上です', u'loginsArea')
    loginUsers = expose(loginUsers)
